optional.hpp
namespace type_safe
{
//=== Basic optional ===//
struct nullopt_t;
constexpr nullopt_t nullopt;
template <typename T>
struct optional_storage_policy_for;
template <class StoragePolicy>
struct optional_storage_policy_for<basic_optional<StoragePolicy>>;
template <typename T>
struct optional_storage_policy_for<T&>;
template <typename T>
struct optional_storage_policy_for<T&&>;
template <class StoragePolicy>
class basic_optional;
template <class StoragePolicy>
bool operator==(const basic_optional<StoragePolicy>& lhs, nullopt_t);
template <class StoragePolicy>
bool operator==(nullopt_t, const basic_optional<StoragePolicy>& rhs);
template <class StoragePolicy>
bool operator!=(const basic_optional<StoragePolicy>& lhs, nullopt_t);
template <class StoragePolicy>
bool operator!=(nullopt_t, const basic_optional<StoragePolicy>& rhs);
template <class StoragePolicy>
bool operator<(const basic_optional<StoragePolicy>& lhs, nullopt_t);
template <class StoragePolicy>
bool operator<(nullopt_t, const basic_optional<StoragePolicy>& rhs);
template <class StoragePolicy>
bool operator<=(const basic_optional<StoragePolicy>& lhs, nullopt_t);
template <class StoragePolicy>
bool operator<=(nullopt_t, const basic_optional<StoragePolicy>& rhs);
template <class StoragePolicy>
bool operator>(const basic_optional<StoragePolicy>& lhs, nullopt_t);
template <class StoragePolicy>
bool operator>(nullopt_t, const basic_optional<StoragePolicy>& rhs);
template <class StoragePolicy>
bool operator>=(const basic_optional<StoragePolicy>& lhs, nullopt_t);
template <class StoragePolicy>
bool operator>=(nullopt_t, const basic_optional<StoragePolicy>& rhs);
//=== Optional value comparison ===//
template <class StoragePolicy, typename U>
bool operator==(const basic_optional<StoragePolicy>& lhs, const U& rhs);
template <class StoragePolicy, typename U>
bool operator==(const U& lhs, const basic_optional<StoragePolicy>& rhs);
template <class StoragePolicy, typename U>
bool operator!=(const basic_optional<StoragePolicy>& lhs, const U& rhs);
template <class StoragePolicy, typename U>
bool operator!=(const U& lhs, const basic_optional<StoragePolicy>& rhs);
template <class StoragePolicy, typename U>
bool operator<(const basic_optional<StoragePolicy>& lhs, const U& rhs);
template <class StoragePolicy, typename U>
bool operator<(const U& lhs, const basic_optional<StoragePolicy>& rhs);
template <class StoragePolicy, typename U>
bool operator<=(const basic_optional<StoragePolicy>& lhs, const U& rhs);
template <class StoragePolicy, typename U>
bool operator<=(const U& lhs, const basic_optional<StoragePolicy>& rhs);
template <class StoragePolicy, typename U>
bool operator>(const basic_optional<StoragePolicy>& lhs, const U& rhs);
template <class StoragePolicy, typename U>
bool operator>(const U& lhs, const basic_optional<StoragePolicy>& rhs);
template <class StoragePolicy, typename U>
bool operator>=(const basic_optional<StoragePolicy>& lhs, const U& rhs);
template <class StoragePolicy, typename U>
bool operator>=(const U& lhs, const basic_optional<StoragePolicy>& rhs);
//=== Optional comparison ===//
template <class StoragePolicy>
bool operator==(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
template <class StoragePolicy>
bool operator!=(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
template <class StoragePolicy>
bool operator<(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
template <class StoragePolicy>
bool operator<=(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
template <class StoragePolicy>
bool operator>(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
template <class StoragePolicy>
bool operator>=(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
template <class Optional, typename Func, typename ... Args>
void with(Optional&& opt, Func&& f, Args&&... additional_args);
//=== Optional ===//
template <typename T>
class direct_optional_storage;
template <typename T>
using optional = basic_optional<direct_optional_storage<T>>;
template <typename T>
using optional_for = basic_optional<direct_optional_storage<int>>::rebind<T>;
template <typename T>
optional<typename std::decay<T>::type> make_optional(T&& t);
template <typename T, typename ... Args>
optional<T> make_optional(Args&&... args);
}
namespace std
{
}
type_safe::nullopt_t
[optional]struct nullopt_t
{
constexpr nullopt_t();
};
Tag type to mark a ts::basic_optional without a value.
type_safe::nullopt
[optional]constexpr nullopt_t nullopt;
Tag object of type ts::nullopt_t.
type_safe::optional_storage_policy_for
[optional]template <typename T>
struct optional_storage_policy_for
{
using type = void;
};
Selects the storage policy used when rebinding a ts::basic_optional.
Some operations like ts::basic_optional::map() change the type of an optional. This traits controls which StoragePolicy
is going to be used for the new optional. You can for example requests a ts::compact_optional_storage for your type, simply specialize it and set a type
typedef.
type_safe::optional_storage_policy_for<basic_optional<StoragePolicy>>
template <class StoragePolicy>
struct optional_storage_policy_for<basic_optional<StoragePolicy>>
{
using type = StoragePolicy;
};
Specialization of ts::optional_storage_policy_for for ts::basic_optional itself.
It will simply forward to the same policy, so ts::optional_for<ts::optional<T>>
is simply ts::optional<T>
, not ts::optional<ts::optional<T>>
. \module optional
type_safe::optional_storage_policy_for<T&>
[optional]template <typename T>
struct optional_storage_policy_for<T&>
{
using type = reference_optional_storage<T>;
};
Specialization of ts::optional_storage_policy_for for lvalue references.
It will use ts::reference_optional_storage as policy.
type_safe::optional_storage_policy_for<T&&>
[optional]template <typename T>
struct optional_storage_policy_for<T&&>
{
};
Specialization of ts::optional_storage_policy_for for rvalue references.
They are not supported.
type_safe::basic_optional
[optional]template <class StoragePolicy>
class basic_optional
{
public:
using storage = StoragePolicy;
using value_type = typename storage::value_type;
template <typename U>
using rebind = 'hidden';
basic_optional() noexcept = default;
basic_optional(nullopt_t) noexcept;
template <typename T>
basic_optional(T&& value);
template <typename T>
basic_optional(T&& value);
basic_optional(const basic_optional& other) = default;
basic_optional(basic_optional&& other) = default;
~basic_optional() noexcept = default;
basic_optional& operator=(nullopt_t) noexcept;
template <typename T>
decltype(std::declval<basic_optional<storage>>().get_storage().create_value(std::forward<T>(value)), *this) operator=(T&& value);
basic_optional& operator=(const basic_optional& other) = default;
basic_optional& operator=(basic_optional&& other) = default;
friend void swap(basic_optional& a, basic_optional& b) noexcept('hidden');
//=== Modifiers ===//
void reset() noexcept;
template <typename ... Args>
decltype(std::declval<basic_optional<storage>>().get_storage().create_value(std::forward<Args>(args)...)) emplace(Args&&... args) noexcept('hidden');
template <typename Arg, typename = typename std::enable_if<detail::is_direct_assignable<decltype(std::declval<storage&>().get_value()), Arg&&>::value>::type>
decltype(std::declval<basic_optional<storage>>().get_storage().create_value(std::forward<Arg>(arg))) emplace(Arg&& arg) noexcept('hidden');
//=== Observers ===//
operator bool() const noexcept;
bool has_value() const noexcept;
decltype(std::declval<storage&>().get_value()) value() & noexcept;
decltype(std::declval<const storage&>().get_value()) value() const & noexcept;
decltype(std::declval<storage&&>().get_value()) value() && noexcept;
decltype(std::declval<const storage&&>().get_value()) value() const && noexcept;
template <typename U>
decltype(std::declval<const storage&>().get_value_or(std::forward<U>(u))) value_or(U&& u) const &;
template <typename U>
decltype(std::declval<storage&&>().get_value_or(std::forward<U>(u))) value_or(U&& u) &&;
template <typename Func, typename ... Args>
'hidden' map(Func&& f, Args&&... args) &;
template <typename Func, typename ... Args>
'hidden' map(Func&& f, Args&&... args) const &;
template <typename Func, typename ... Args>
'hidden' map(Func&& f, Args&&... args) &&;
template <typename Func, typename ... Args>
'hidden' map(Func&& f, Args&&... args) const &&;
};
An optional type, i.e. a type that may or may not be there.
It is similar to std::optional<T> but lacks some functions and provides some others. It can be in one of two states: it contains a value of a certain type or it does not (it is "empty").
The storage itself is managed via the StoragePolicy
. It must provide the following members:
value_type
- the type stored in the optional(const_)lvalue_reference
- const
lvalue reference type(const_)rvalue_reference
- const
rvalue reference typerebind<U>
- the same policy for a different typeStoragePolicy() noexcept
- a no-throw default constructor that initializes it in the "empty" statevoid create_value(Args&&... args)
- creates a value by forwarding the arguments to its constructorvoid create_value_explicit(T&& obj)
- creates a value requiring an explicit
constructorvoid create_value(const StoragePolicy&/StoragePolicy&&)
- creates a value by using the value stored in the other policyvoid copy_value(const StoragePolicy&/StoragePolicy&&)
- similar to above, but *this may contain a value alreadyvoid swap_value(StoragePolicy&)
- swaps the stored value (if any) with the one in the other policyvoid destroy_value() noexcept
- calls the destructor of the value, afterwards the storage is "empty"bool has_value() const noexcept
- returns whether or not there is a value, i.e. create_value()
has been called but destroy_value()
has notU get_value() (const)& noexcept
- returns a reference to the stored value, U is one of the XXX_reference
typedefsU get_value() (const)&& noexcept
- returns a reference to the stored value, U is one of the XXX_reference
typedefsU get_value_or(T&& val) [const&/&&]
- returns either get_value()
or val
U get_value_or(T&& val) [const&/&&]
- returns either get_value()
or val
type_safe::basic_optional::rebind
template <typename U>
using rebind = 'hidden';
Rebinds the current optional to the type U
.
It will use ts::optional_storage_policy_for to determine whether a change of storage policy is needed. \notes If U
is void
, the result will be void
as well. \notes Due to a specialization of ts::optional_storage_policy_for, if U
is an optional itself, the result will be U
, not an optional of an optional. \exclude target
type_safe::basic_optional::basic_optional
(1) basic_optional() noexcept = default;
(2) basic_optional(nullopt_t) noexcept;
Effects: Creates it without a value.
type_safe::basic_optional::basic_optional
template <typename T>
basic_optional(T&& value);
Effects: Creates it with a value by forwarding value
.
Throws: Anything thrown by the constructor of value_type
.
Requires: The create_value()
function of the StoragePolicy
must accept value
.
type_safe::basic_optional::basic_optional
template <typename T>
basic_optional(T&& value);
Effects: Creates it with a value by forwarding value
.
Throws: Anything thrown by the constructor of value_type
.
Requires: The create_value_explicit()
function of the StoragePolicy
must accept value
.
type_safe::basic_optional::basic_optional
basic_optional(const basic_optional& other) = default;
Copy constructor.
Effects: If other
does not have a value, it will be created without a value as well. If other
has a value, it will be created with a value by copying other.value()
.
Throws: Anything thrown by the copy constructor of value_type
if other
has a value.
Notes: This constructor will not participate in overload resolution, unless the value_type
is copy constructible.
type_safe::basic_optional::basic_optional
basic_optional(basic_optional&& other) = default;
Move constructor.
Effects: If other
does not have a value, it will be created without a value as well. If other
has a value, it will be created with a value by moving other.value()
.
Throws: Anything thrown by the move constructor of value_type
if other
has a value.
Notes: other
will still have a value after the move operation, it is just in a moved-from state.
Notes: This constructor will not participate in overload resolution, unless the value_type
is move constructible.
type_safe::basic_optional::~basic_optional
~basic_optional() noexcept = default;
Destructor.
Effects: If it has a value, it will be destroyed.
type_safe::basic_optional::operator=
basic_optional& operator=(nullopt_t) noexcept;
Effects: Same as reset()
.
type_safe::basic_optional::operator=
template <typename T>
decltype(std::declval<basic_optional<storage>>().get_storage().create_value(std::forward<T>(value)), *this) operator=(T&& value);
Effects: Same as emplace(std::forward<T>(t))
.
Requires: The call to emplace()
must be well-formed.
type_safe::basic_optional::operator=
basic_optional& operator=(const basic_optional& other) = default;
Copy assignment operator.
Effects: If other
has a value, does something equivalent to emplace(other.value())
(this will always trigger the single parameter version). Otherwise will reset the optional to the empty state. \throws Anything thrown by the call to emplace()
. \notes This operator will not participate in overload resolution, unless the value_type
is copy constructible.
type_safe::basic_optional::operator=
basic_optional& operator=(basic_optional&& other) = default;
Move assignment operator.
Effects: If other
has a value, does something equivalent to emplace(std::move(other).value())
(this will always trigger the single parameter version). Otherwise will reset the optional to the empty state.
Throws: Anything thrown by the call to emplace()
.
Notes: This operator will not participate in overload resolution, unless the value_type
is copy constructible.
type_safe::swap
friend void swap(basic_optional& a, basic_optional& b) noexcept('hidden');
Effects: Swap. If both a
and b
have values, swaps the values with their swap function. Otherwise, if only one of them have a value, moves that value to the other one and makes the moved-from empty. Otherwise, if both are empty, does nothing. \throws Anything thrown by the move construction or swap.
type_safe::basic_optional::reset
void reset() noexcept;
Effects: Destroys the value by calling its destructor, if there is any stored. Afterwards has_value()
will return false
.
type_safe::basic_optional::emplace
template <typename ... Args>
decltype(std::declval<basic_optional<storage>>().get_storage().create_value(std::forward<Args>(args)...)) emplace(Args&&... args) noexcept('hidden');
Effects: First destroys any old value like reset()
. Then creates the value by perfectly forwarding args...
to the constructor of value_type
.
Throws: Anything thrown by the constructor of value_type
. If this function is left by an exception, the optional will be empty.
Notes: If the create_value()
function of the StoragePolicy
does not accept the arguments, this function will not participate in overload resolution. \synopsis_return void
type_safe::basic_optional::emplace
template <typename Arg, typename = typename std::enable_if<detail::is_direct_assignable<decltype(std::declval<storage&>().get_value()), Arg&&>::value>::type>
decltype(std::declval<basic_optional<storage>>().get_storage().create_value(std::forward<Arg>(arg))) emplace(Arg&& arg) noexcept('hidden');
Effects: If has_value()
is false
creates it by calling the constructor with arg
perfectly forwarded. Otherwise assigns a perfectly forwarded arg
to value()
. \throws Anything thrown by the constructor or assignment operator chosen. \notes This function does not participate in overload resolution unless there is an operator=
that takes arg
without an implicit user-defined conversion and the create_value()
function of the StoragePolicy
accepts the argument. \synopsis_return void
type_safe::basic_optional::operator bool
operator bool() const noexcept;
Returns: The same as has_value()
.
type_safe::basic_optional::has_value
bool has_value() const noexcept;
Returns: Whether or not the optional has a value.
type_safe::basic_optional::value
(1) decltype(std::declval<storage&>().get_value()) value() & noexcept;
(2) decltype(std::declval<const storage&>().get_value()) value() const & noexcept;
(3) decltype(std::declval<storage&&>().get_value()) value() && noexcept;
(4) decltype(std::declval<const storage&&>().get_value()) value() const && noexcept;
Access to the stored value.
Returns: A reference to the stored value. The exact type depends on the StoragePolicy
.
Requires: has_value() == true
.
type_safe::basic_optional::value_or
template <typename U>
decltype(std::declval<const storage&>().get_value_or(std::forward<U>(u))) value_or(U&& u) const &;
Returns: If it has a value, value()
, otherwise u
converted to the same type as value()
. \requires u
must be valid argument to the value_or()
function of the StoragePolicy
. \notes Depending on the StoragePolicy
, this either returns a decayed type or a reference. \group value_or
type_safe::basic_optional::value_or
(1) template <typename U>
decltype(std::declval<storage&&>().get_value_or(std::forward<U>(u))) value_or(U&& u) &&;
type_safe::basic_optional::map
(1) template <typename Func, typename ... Args>
'hidden' map(Func&& f, Args&&... args) &;
(2) template <typename Func, typename ... Args>
'hidden' map(Func&& f, Args&&... args) const &;
(3) template <typename Func, typename ... Args>
'hidden' map(Func&& f, Args&&... args) &&;
(4) template <typename Func, typename ... Args>
'hidden' map(Func&& f, Args&&... args) const &&;
Maps an optional.
Effects: If the optional contains a value, calls the function with the value followed by the additional arguments perfectly forwarded.
Returns: A basic_optional
rebound to the result type of the function, that is empty if *this
is empty and contains the result of the function otherwise.
Requires: f
must either be a function or function object of matching signature, or a member function pointer of the stored type with compatible signature.
Notes: Due to the way ts::basic_optional::rebind works, if the result of the function is void
, map()
will return void
as well, and if the result of the function is an optional itself, map()
will return the optional unchanged.
type_safe::operator==
template <class StoragePolicy>
bool operator==(const basic_optional<StoragePolicy>& lhs, nullopt_t);
Comparison of ts::basic_optional with ts::nullopt.
An optional is equal to ts::nullopt if it does not have a value. Nothing is less than ts::nullopt, it is only less than an optional, A optional compares equal to nullopt
, when it does not have a value. A optional compares never less to nullopt
, nullopt
compares less only if the optional has a value. The other comparisons behave accordingly. \group optional_comp_null Optional null comparison \module optional
type_safe::operator==
(1) template <class StoragePolicy>
bool operator==(nullopt_t, const basic_optional<StoragePolicy>& rhs);
(2) template <class StoragePolicy>
bool operator!=(const basic_optional<StoragePolicy>& lhs, nullopt_t);
(3) template <class StoragePolicy>
bool operator!=(nullopt_t, const basic_optional<StoragePolicy>& rhs);
(4) template <class StoragePolicy>
bool operator<(const basic_optional<StoragePolicy>& lhs, nullopt_t);
(5) template <class StoragePolicy>
bool operator<(nullopt_t, const basic_optional<StoragePolicy>& rhs);
(6) template <class StoragePolicy>
bool operator<=(const basic_optional<StoragePolicy>& lhs, nullopt_t);
(7) template <class StoragePolicy>
bool operator<=(nullopt_t, const basic_optional<StoragePolicy>& rhs);
(8) template <class StoragePolicy>
bool operator>(const basic_optional<StoragePolicy>& lhs, nullopt_t);
(9) template <class StoragePolicy>
bool operator>(nullopt_t, const basic_optional<StoragePolicy>& rhs);
(10) template <class StoragePolicy>
bool operator>=(const basic_optional<StoragePolicy>& lhs, nullopt_t);
(11) template <class StoragePolicy>
bool operator>=(nullopt_t, const basic_optional<StoragePolicy>& rhs);
(1) template <class StoragePolicy, typename U>
bool operator==(const basic_optional<StoragePolicy>& lhs, const U& rhs);
(2) template <class StoragePolicy, typename U>
bool operator==(const U& lhs, const basic_optional<StoragePolicy>& rhs);
(3) template <class StoragePolicy, typename U>
bool operator!=(const basic_optional<StoragePolicy>& lhs, const U& rhs);
(4) template <class StoragePolicy, typename U>
bool operator!=(const U& lhs, const basic_optional<StoragePolicy>& rhs);
(5) template <class StoragePolicy, typename U>
bool operator<(const basic_optional<StoragePolicy>& lhs, const U& rhs);
(6) template <class StoragePolicy, typename U>
bool operator<(const U& lhs, const basic_optional<StoragePolicy>& rhs);
(7) template <class StoragePolicy, typename U>
bool operator<=(const basic_optional<StoragePolicy>& lhs, const U& rhs);
(8) template <class StoragePolicy, typename U>
bool operator<=(const U& lhs, const basic_optional<StoragePolicy>& rhs);
(9) template <class StoragePolicy, typename U>
bool operator>(const basic_optional<StoragePolicy>& lhs, const U& rhs);
(10) template <class StoragePolicy, typename U>
bool operator>(const U& lhs, const basic_optional<StoragePolicy>& rhs);
(11) template <class StoragePolicy, typename U>
bool operator>=(const basic_optional<StoragePolicy>& lhs, const U& rhs);
(12) template <class StoragePolicy, typename U>
bool operator>=(const U& lhs, const basic_optional<StoragePolicy>& rhs);
Compares a ts::basic_optional with a value.
An optional compares equal to a value if it has a value and the value compares equal. An optional compares less to a value if it does not have a value or the value compares less. A value compares less to an optional if the optional has a value and the value compares less than the optional. The other comparisons behave accordingly.
Value comparison is done by the comparison operator of the value_type
, a function only participates in overload resolution if the value_type
, has that comparison function.
(1) template <class StoragePolicy>
bool operator==(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
(2) template <class StoragePolicy>
bool operator!=(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
(3) template <class StoragePolicy>
bool operator<(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
(4) template <class StoragePolicy>
bool operator<=(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
(5) template <class StoragePolicy>
bool operator>(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
(6) template <class StoragePolicy>
bool operator>=(const basic_optional<StoragePolicy>& lhs, const basic_optional<StoragePolicy>& rhs);
Compares two ts::basic_optional objects.
If lhs
has a value, forwards to lhs.value() <op> rhs
. Else forwards to nullopt <op> rhs
.
type_safe::with
[optional]template <class Optional, typename Func, typename ... Args>
void with(Optional&& opt, Func&& f, Args&&... additional_args);
With operation for ts::optional.
Effects: Calls the operator()
of f
passing it the value of opt
and additional arguments, if it has a value. Otherwise does nothing.
type_safe::direct_optional_storage
[optional]template <typename T>
class direct_optional_storage
{
public:
using value_type = typename std::remove_cv<T>::type;
using lvalue_reference = T&;
using const_lvalue_reference = const T&;
using rvalue_reference = T&&;
using const_rvalue_reference = const T&&;
template <typename U>
using rebind = direct_optional_storage<U>;
direct_optional_storage() noexcept;
template <typename ... Args>
typename std::enable_if<std::is_constructible<value_type, Args&&...>::value>::type create_value(Args&&... args);
void create_value(const direct_optional_storage& other);
void create_value(direct_optional_storage&& other);
void create_value_explicit();
void copy_value(const direct_optional_storage& other);
void copy_value(const direct_optional_storage& other);
void copy_value(direct_optional_storage&& other);
void copy_value(direct_optional_storage&& other);
void swap_value(direct_optional_storage& other);
void destroy_value() noexcept;
bool has_value() const noexcept;
lvalue_reference get_value() & noexcept;
const_lvalue_reference get_value() const & noexcept;
rvalue_reference get_value() && noexcept;
const_rvalue_reference get_value() const && noexcept;
template <typename U, typename = typename std::enable_if<std::is_copy_constructible<value_type>::value&&std::is_convertible<U&&, value_type>::value>::type>
value_type get_value_or(U&& u) const &;
template <typename U>
value_type get_value_or(U&& u) &&;
};
A StoragePolicy
for ts::basic_optional that is similar to std::optional<T>'s implementation.
It uses std::aligned_storage and a bool
flag whether a value was created.
Requires: T
must not be a reference.
type_safe::direct_optional_storage::direct_optional_storage
direct_optional_storage() noexcept;
Effects: Initializes it in the state without value.
type_safe::direct_optional_storage::create_value
template <typename ... Args>
typename std::enable_if<std::is_constructible<value_type, Args&&...>::value>::type create_value(Args&&... args);
Effects: Calls the constructor of value_type
by perfectly forwarding args
. Afterwards has_value()
will return true
.
Throws: Anything thrown by the constructor of value_type
in which case has_value()
is still false
. \requires has_value() == false
. \notes This function does not participate in overload resolution unless value_type
is constructible from args
. \synopsis_return void
type_safe::direct_optional_storage::create_value
(1) void create_value(const direct_optional_storage& other);
(2) void create_value(direct_optional_storage&& other);
Effects: Creates a value by copy(1)/move(2) constructing from the value stored in other
, if there is any.
type_safe::direct_optional_storage::copy_value::copy_value
(1) void copy_value(const direct_optional_storage& other);
(2) void copy_value(const direct_optional_storage& other);
Effects: Copies the policy from other
, by copy-constructing or assigning the stored value, if any.
Throws: Anything thrown by the copy constructor or copy assignment operator of other
.
type_safe::direct_optional_storage::copy_value::copy_value
(1) void copy_value(direct_optional_storage&& other);
(2) void copy_value(direct_optional_storage&& other);
Effects: Copies the policy from other
, by move-constructing or assigning the stored value, if any.
Throws: Anything thrown by the move constructor or move assignment operator of other
.
type_safe::direct_optional_storage::swap_value
void swap_value(direct_optional_storage& other);
Effects: Swaps the value with the value in other
.
type_safe::direct_optional_storage::destroy_value
void destroy_value() noexcept;
Effects: Calls the destructor of value_type
. Afterwards has_value()
will return false
.
Requires: has_value() == true
.
type_safe::direct_optional_storage::has_value
bool has_value() const noexcept;
Returns: Whether or not there is a value stored.
type_safe::direct_optional_storage::get_value
(1) lvalue_reference get_value() & noexcept;
(2) const_lvalue_reference get_value() const & noexcept;
(3) rvalue_reference get_value() && noexcept;
(4) const_rvalue_reference get_value() const && noexcept;
Returns: A (const
) (rvalue) reference to the stored value.
Requires: has_value() == true
.
type_safe::direct_optional_storage::get_value_or
template <typename U, typename = typename std::enable_if<std::is_copy_constructible<value_type>::value&&std::is_convertible<U&&, value_type>::value>::type>
value_type get_value_or(U&& u) const &;
Returns: Either get_value()
or u
converted to value_type
.
Requires: value_type
must be copy(1)/move(2) constructible and u
convertible to value_type
. \group get_value_or \param 1 \exclude
type_safe::direct_optional_storage::get_value_or
(1) template <typename U>
value_type get_value_or(U&& u) &&;
type_safe::optional
[optional]template <typename T>
using optional = basic_optional<direct_optional_storage<T>>;
A ts::basic_optional that uses ts::direct_optional_storage<T>.
type_safe::optional_for
[optional]template <typename T>
using optional_for = basic_optional<direct_optional_storage<int>>::rebind<T>;
Uses ts::optional_storage_policy_for to select the appropriate ts::basic_optional.
By default, it uses ts::direct_optional_storage.
Notes: If T
is void
, optional_for
will also be void
.
type_safe::make_optional
[optional]template <typename T>
optional<typename std::decay<T>::type> make_optional(T&& t);
Returns: A new ts::optional<T> storing a copy of t
.
type_safe::make_optional
template <typename T, typename ... Args>
optional<T> make_optional(Args&&... args);
Returns: A new ts::optional<T> with a value created by perfectly forwarding args
to the constructor. \module optional